package com.jeesite.modules.yzw.service;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.jeesite.common.codec.Md5Utils;
import com.jeesite.common.config.Global;
import com.jeesite.common.lang.StringUtils;
import com.jeesite.modules.yzw.entity.SmsSet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import javax.validation.constraints.NotBlank;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 短信工具类
 */
@Component
public class SmsClient {

    @Autowired
    private RestTemplate restTemplate;

    private static SmsSet smsSet;

    public static String Success="Success";

    private static ThreadPoolExecutor smsThreadPoolExecutor = new ThreadPoolExecutor(
            1,
            10,
            5,
            TimeUnit.SECONDS,
            new LinkedBlockingQueue<>(1000),
            new ThreadPoolExecutor.CallerRunsPolicy()
    );

    static {
        String config = /*Global.getConfig("sys.platform.smsclient");*/"";
        if (StringUtils.isNotBlank(config)){
            smsSet = JSON.parseObject(config, SmsSet.class);
        }
    }

    /**
     * 同步发送
     * @return
     */
    public boolean sendSms(@NotBlank String mobile, @NotBlank String content){
        try {
            MultiValueMap<String, Object> requestMsg = getRequestMsg("send",mobile,content);
            Map resultMap = restTemplate.postForObject(smsSet.getPlatformUrl(), requestMsg, Map.class);
            return Success.equals(resultMap.get("ReturnStatus"));
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 同步发送
     * @return
     */
    public Map<String,Object> sendSmsResultMap(@NotBlank String mobile, @NotBlank String content){
        try {
            MultiValueMap<String, Object> requestMsg = getRequestMsg("send",mobile,content);
            return restTemplate.postForObject(smsSet.getPlatformUrl(), requestMsg, Map.class);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 异步发送
     * @return
     */
    public void sendSmsAsync(@NotBlank String mobile, @NotBlank String content){
        CompletableFuture.runAsync(()->{
            try {
                MultiValueMap<String, Object> requestMsg = getRequestMsg("send",mobile,content);
                restTemplate.postForObject(smsSet.getPlatformUrl(), requestMsg, Map.class);
            } catch (Exception e) {
                e.printStackTrace();
            }
        },smsThreadPoolExecutor);
    }

    /**
     * 批量发送短信
     */
    public void sendSmsList(List<Map<String,String>> phones){
        if (CollectionUtils.isEmpty(phones)){
            return;
        }
        CollUtil.split(phones,20).forEach(x->{
            CompletableFuture.runAsync(()->{
                x.forEach(phone->{
                    sendSms(phone.get("phone"),phone.get("context"));
                });
            },smsThreadPoolExecutor);
        });
    }



    /**
     * 构建短信参数
     * @param action
     * @param mobile
     * @param content
     * @return
     */
    public  MultiValueMap<String,Object> getRequestMsg(String action,String mobile,String content){
        Assert.notNull(smsSet,"获取短信配置失败！");
        Date date = new Date();
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
        MultiValueMap<String, Object> requestMap = new LinkedMultiValueMap<>();
        requestMap.add("timestamp",df.format(date));
        requestMap.add("userid",smsSet.getUserId());
        requestMap.add("rt","json");
        requestMap.add("mobile",mobile);
        requestMap.add("content",smsSet.getHeadSign()+content);
        requestMap.add("action",action);
        requestMap.add("sign",Md5Utils.md5(smsSet.getUserName()+smsSet.getPassWord()+df.format(date)));
        return requestMap;
    }

}
